﻿using System;
using System.Collections.Generic;
using System.Text;

using LoginServer.Manager;
using LoginServer.Networking.Packets;

namespace LoginServer.Networking.Handlers
{
    class HANDLE_LOGIN : PacketHandler
    {
        private enum LoginState { Success = 1, UnknownUser, InvalidPassword, AlreadyLoggedIn, Banned, Unknown };

        public override void Handle(LoginServer.Virtual_Objects.User.virtualUser Connection)
        {
            DateTime current = DateTime.Now;
            int StartTime = int.Parse(String.Format("{0:yyMMddHH}", current));
            Connection.Username = getBlock(2).ToLower();
            string Password = getBlock(3).ToLower();
            try
            {
                LoginState ReturnValue = LoginState.Unknown;
                int UserID = DB.runRead("SELECT id FROM users WHERE username='" + DB.Stripslash(Connection.Username) + "'", null);
                if (UserID > 0)
                {
                    string[] UserData = DB.runReadRow("SELECT id, username, password, salt, online, nickname, rank, firstlogin, bantime FROM users WHERE id=" + UserID.ToString());
                    if (UserData[2].ToLower() == Password.ToLower())
                    {
                        if (BanManager.isBlocked(UserID) == false && RankManager.HasPermision(int.Parse(UserData[6]), "account.authorize"))
                        {
                            if (UserData[4].Equals("1"))
                            {
                                ReturnValue = LoginState.AlreadyLoggedIn;
                                Connection.send(new PACKET_SERVER_LIST(PACKET_SERVER_LIST.errorCodes.AlreadyLoggedIn));
                                Log.WriteLine("Connection from " + Connection.IPAddress + " logged succesfull in as " + UserData[5] + " but the user is already online.");
                            }
                            else
                            {
                                ReturnValue = LoginState.Success;
                                if (UserData[7].Equals("0"))
                                {
                                    Connection.UserID = UserID;
                                    Connection.send(new PACKET_SERVER_LIST(PACKET_SERVER_LIST.errorCodes.Nickname));
                                    Log.WriteLine("Connection from " + Connection.IPAddress + " logged succesfull in as " + UserData[5] + ".");

                                }
                                else
                                {
                                    Connection.send(new PACKET_SERVER_LIST(int.Parse(UserData[0]), UserData[1], Password, UserData[5], Connection.SessionID, int.Parse(UserData[6])));
                                    Log.WriteLine("Connection from " + Connection.IPAddress + " logged succesfull in as " + UserData[5] + ".");
                                }
                                Program._AcceptedLogins++;
                                Program._PlayerCount++;
                            }
                        }
                        else
                        {
                            if (int.Parse(UserData[8]) > StartTime)
                            {
                                ReturnValue = LoginState.Banned;
                                Connection.send(new PACKET_SERVER_LIST(PACKET_SERVER_LIST.errorCodes.Banned));
                                Log.WriteError("Connection from " + Connection.IPAddress + " failed to login because the account " + UserData[1] + " is disabled/banned.");
                            }
                            else
                            {
                                DB.runQuery("UPDATE users SET rank='1', bantime='-1' WHERE id='" + UserData[0] + "'");
                                Connection.send(new PACKET_SERVER_LIST(int.Parse(UserData[0]), UserData[1], Password, UserData[5], Connection.SessionID, int.Parse(UserData[6])));
                                Log.WriteLine("Connection from " + Connection.IPAddress + " logged succesfull in as " + UserData[5] + ".");
                            }
                        }
                    }
                    else
                    {
                        ReturnValue = LoginState.InvalidPassword;
                        Connection.send(new PACKET_SERVER_LIST(PACKET_SERVER_LIST.errorCodes.WrongPW));
                        Log.WriteError("Connection from " + Connection.IPAddress + " failed to login on the account " + UserData[1] + ".");
                    }
                }
                else
                {
                    UserID = -1;
                    ReturnValue = LoginState.UnknownUser;
                    Connection.send(new PACKET_SERVER_LIST(PACKET_SERVER_LIST.errorCodes.WrongUser));
                    Log.WriteError("Connection from " + Connection.IPAddress + " logged in with an invalid username: " + Connection.Username + ".");
                }
                //DB.runQuery("INSERT INTO log_authorize (`time`, `userid`, `username`, `password`, `result`, `ip`, `host`) VALUES ('" + Program.UnixTimestamp + "', '" + UserID + "', '" + DB.Stripslash(Connection.Username) + "', '" + DB.Stripslash(Password) + "', '" + ((int)ReturnValue).ToString() + "', '" + Connection.IPAddress + "', '" + Connection.Hostname + "');");
            }
            catch (Exception ex)
            {
                Connection.disconnect();
                Log.WriteError(ex.Message);
            }
        }

        private static String hashMD5(String Input)
        {
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(Input);
            byte[] hash = md5.ComputeHash(inputBytes);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString();
        }
    }
}
